package library.net.retrofit.interceptor;

import java.io.UnsupportedEncodingException;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * @author Created by qiang.hou on 2017/12/14.
 * @version 1.0
 */
public class RxCommonParamsInterceptor extends BaseParamsInterceptor {

    private RxCommonParamsInterceptor() {
        super.control = Type.ADD;
    }

    private RxCommonParamsInterceptor(Type t) {
        super.control = t;
    }

    /**
     * add param
     *
     * @param key   key
     * @param value value
     */
    private void addParam(String key, Object value) {
        if (contentMap.containsKey(key)) {
            contentMap.remove(key);
        }
        contentMap.put(key, value);
    }

    /**
     * add params
     *
     * @param paramsMap mParamsMap
     */
    public void addParams(Map<String, Object> paramsMap) {
        for (Map.Entry<String, Object> params : paramsMap.entrySet()) {
            addParam(params.getKey(), params.getValue());
        }
    }

    /**
     * remove param
     *
     * @param key key for param
     */
    public void removeParam(String key) {
        if (contentMap.containsKey(key)) {
            contentMap.remove(key);
        }
    }

    /**
     * clear headers
     */
    public void clearParams() {
        contentMap.clear();
    }

    @Override
    Request interceptor(Request request) throws UnsupportedEncodingException {
        // 添加公共参数
        if (null != contentMap && contentMap.size() > 0) {
            if (("GET").equals(request.method())) {
                // GET
                HttpUrl httpUrl = request.url();
                HttpUrl.Builder requestUrlBuilder = httpUrl.newBuilder();
                for (Map.Entry<String, Object> params : contentMap.entrySet()) {
                    switch (super.control) {
                        case ADD:
                            requestUrlBuilder.addQueryParameter(params.getKey(),
                                    params.getValue() == null ? "" : getValueEncoded(params.getValue().toString())).build();
                            break;
                        case UPDATE:
                            requestUrlBuilder.setQueryParameter(params.getKey(),
                                    params.getValue() == null ? "" : getValueEncoded(params.getValue().toString())).build();
                            break;
                        case REMOVE:
                            requestUrlBuilder.removeAllQueryParameters(params.getKey()).build();
                            break;
                        default:
                            break;
                    }
                }
                return request.newBuilder().url(requestUrlBuilder.build()).build();
            } else if ("POST".equals(request.method())) {
                // POST
                RequestBody requestBody = request.body();
                if (requestBody != null && requestBody instanceof FormBody) {
                    // POST Param x-www-form-urlencoded
                    FormBody.Builder bodyBuilder = new FormBody.Builder();
                    FormBody formBody = (FormBody) requestBody;
                    int bodySize = formBody.size();
                    for (int i = 0; i < bodySize; i++) {
                        bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
                    }

                    for (Map.Entry<String, Object> entry : contentMap.entrySet()) {
                        bodyBuilder.addEncoded(entry.getKey(), getValueEncoded(entry.getValue().toString()));
                    }
                    return request.newBuilder().post(bodyBuilder.build()).build();
                } else if (requestBody != null && requestBody instanceof MultipartBody) {
                    // POST Param form-data
                    MultipartBody.Builder newBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                    for (Map.Entry<String, Object> entry : contentMap.entrySet()) {
                        newBuilder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                    }
                    MultipartBody multipartBody = (MultipartBody) requestBody;
                    for (MultipartBody.Part part : multipartBody.parts()) {
                        newBuilder.addPart(part);
                    }
                    return request.newBuilder().post(newBuilder.build()).build();
                } else {
                    return request;
                }
            } else {
                return request;
            }
        } else {
            return request;
        }
    }
}
